//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include "ConvertMol2ToSmileJChem.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>

#include <iostream>
#include <fstream>
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#define LENGTHLINE 50000
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
using namespace std;
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ConvertMol2ToSmileJChem::ConvertMol2ToSmileJChem() {
  this->locationDB      = new String();
  this->filenameOut     = new String();
  this->listLigandError = new String();
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ConvertMol2ToSmileJChem::ConvertMol2ToSmileJChem(const ConvertMol2ToSmileJChem& convertMol2ToSmileJChem) {
  this->locationDB      = new String(convertMol2ToSmileJChem.locationDB);
  this->filenameOut     = new String(convertMol2ToSmileJChem.filenameOut);
  this->listLigandError = new String(convertMol2ToSmileJChem.listLigandError);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ConvertMol2ToSmileJChem::ConvertMol2ToSmileJChem(const ConvertMol2ToSmileJChem* convertMol2ToSmileJChem) {
  this->locationDB      = new String(convertMol2ToSmileJChem->locationDB);
  this->filenameOut     = new String(convertMol2ToSmileJChem->filenameOut);
  this->listLigandError = new String(convertMol2ToSmileJChem->listLigandError);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ConvertMol2ToSmileJChem::~ConvertMol2ToSmileJChem() {
  if (this->locationDB)      delete this->locationDB;
  if (this->filenameOut)     delete this->filenameOut;
  if (this->listLigandError) delete this->listLigandError;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void ConvertMol2ToSmileJChem::LocationDB(String* locationDB) {

  if (locationDB) {
    if (this->locationDB) delete this->locationDB;
    this->locationDB = locationDB;
  }
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void ConvertMol2ToSmileJChem::FilenameOut(String* filenameOut) {

  if (filenameOut) {
    if (this->filenameOut) delete this->filenameOut;
    this->filenameOut = filenameOut;
  }
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void ConvertMol2ToSmileJChem::ListLigandError(String* listLigandError) {

  if (listLigandError) {
    if (this->listLigandError) delete this->listLigandError;
    this->listLigandError = listLigandError;
  }
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* ConvertMol2ToSmileJChem::LocationDB(void) {
  return this->locationDB;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* ConvertMol2ToSmileJChem::FilenameOut(void) {
  return this->filenameOut;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* ConvertMol2ToSmileJChem::ListLigandError(void) {
  return this->listLigandError;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool ConvertMol2ToSmileJChem::ConvertMol2LigandsToSmiles() {

  if (!this->locationDB      || !this->locationDB->Length()  ||
      !this->filenameOut     || !this->filenameOut->Length() ||
      !this->listLigandError || !this->listLigandError->Length())
    return false;

  TListE <String> *listFiles = new TListE <String> ();

  /*Load the path for all pdb file inside the selected location*/
  struct dirent **namelist;
  int             n;

  n = scandir(this->locationDB->Out(), &namelist, 0, alphasort);

  if (n >= 0) {

    while(n--) {

      if (strcmp(namelist[n]->d_name, ".") && strcmp(namelist[n]->d_name, "..")) {
        String* nameFile = new String(namelist[n]->d_name);
        listFiles->Add(nameFile);
      }

      free(namelist[n]);

    }

    free(namelist);

  }

  char    buffer[LENGTHLINE + 1];
  char*   completePath  = NULL;
  char*   completePathT = NULL;
  char*   command       = NULL;
  
  fstream tmpResult;
  fstream fileOut;
  fstream fileError;
  
  fileOut.open(this->filenameOut->Out(), fstream::out);
  fileError.open(this->listLigandError->Out(), fstream::out);

  cout << "Reading Files (" << listFiles->Length() << ")..." << endl;
  cout << "---------------------------------------------------------------------------------" << endl;

  listFiles->SetInitial();

  while (listFiles->SetNext()) {

    completePathT = new char[strlen(this->locationDB->Out()) + strlen(listFiles->GetCurrent()->Out())     +  30];
    completePath  = new char[strlen(this->locationDB->Out()) + strlen(listFiles->GetCurrent()->Out())     +  10];
    command       = new char[2*strlen(this->locationDB->Out()) + 2*strlen(listFiles->GetCurrent()->Out()) + 100];

    sprintf(completePathT, "%s%s.tmp\0", this->locationDB->Out(), listFiles->GetCurrent()->Out());
    sprintf(completePath,  "%s%s\0",     this->locationDB->Out(), listFiles->GetCurrent()->Out());
    sprintf(command, "./molconvert smiles %s > %s\0", completePath, completePathT);

    cout << "File :" << completePath << endl;
    cout << "---------------------------------------------------------------------------------" << endl;
    cout << command << endl;
    system(command);
    cout << "---------------------------------------------------------------------------------" << endl;

    tmpResult.open(completePathT, fstream::in);

    int     counter  = 0;
    bool    isResult = true;
    String* smiles   = new String();

    while (!tmpResult.eof()) {

      tmpResult.getline(buffer, LENGTHLINE);
      if (!counter++) smiles->In(buffer);
      String* line = new String(buffer);

      if (line->Contain("error")) { 
        isResult = false;
        if (line) delete line;
        break;
      }
      if (line) delete line;
      
    }

    tmpResult.close();

    cout << "---------------------------------------------------------------------------------" << endl;
    if (isResult && smiles->Length()) {
      fileOut << smiles->Out() << " " << listFiles->GetCurrent()->Out() << endl;
      cout    << smiles->Out() << " " << listFiles->GetCurrent()->Out() << endl;
    }
    else 
      fileError << listFiles->GetCurrent()->Out() << endl;

    if (smiles) delete smiles;

    sprintf(command, "rm %s\0", completePathT);
    cout << command << endl;
    system(command);
    
    if (completePathT) delete[] completePathT;
    if (completePath)  delete[] completePath;
    if (command)       delete[] command;

  }

  fileOut.close();
  fileError.close();

  if (listFiles) delete listFiles;

  return true;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
